import time
from time import sleep
import matplotlib.pyplot as plt
import matplotlib
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util import Retry
from datetime import datetime
from codeforces.tables import rating_color, AC_Rank_Time, Rating_Rank_time
from utils.mydate import getMonday, formatDate, formatSeconds
from codeforces.model import UserSubmission
from codeforces.atcoder import get_atcoder_contests
from codeforces.newcoder import get_nowcoder_contests

url_reboot = "http://127.0.0.1:5700"
url_cf = "http://codeforces.com/api"

RES = requests.session()
RES.mount('http://', HTTPAdapter(max_retries=Retry(total=5)))
RES.mount('https://', HTTPAdapter(max_retries=Retry(total=5)))

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'
}


# 获取 rating 排名
def getUserRatingRank(user_name):
    handles = ""
    for handle in user_name.keys():  # 取出 key 值（用户名）
        handles = handles + handle + ";"
    params = {
        "handles": handles
    }
    response = RES.get(url=url_cf + "/user.info", params=params)
    while response.status_code != 200:
        response = RES.get(url=url_cf + "/user.info", params=params)
    res = response.json().get("result")
    users = []
    for i in range(0, len(res)):
        user = (user_name[res[i].get("handle").lower()],  # 真实姓名
                res[i].get("handle"),  # 用户名
                0 if res[i].get("rating") is None else res[i].get("rating"),  # 分数
                rating_color[res[i].get("rank")])  # 颜色
        users.append(user)
    users.sort(key=lambda x: (x[2]), reverse=False)
    imgx = []
    imgy = []
    colors = []
    for i in range(0,len(users)) :
        imgx.append(users[i][0])
        imgy.append(users[i][2])
        colors.append(getColor(users[i][3]))
    matplotlib.rcParams['font.sans-serif'] = ["SimHei"]
    matplotlib.rcParams["axes.unicode_minus"] = False
    plt.figure(figsize=(10, 15))
    plt.barh(imgx, imgy,height=0.5,color=colors)
    plt.title("cf rating rank")
    plt.xlabel("分数")
    plt.ylabel("姓名")
    for i,v in enumerate(imgy):
        plt.text(v+1,i,str(v),fontweight='bold')
    filename = "E:\go_chttp\data\images\\cf_rating_rank.png"
    plt.savefig(filename)
    return "[CQ:image,file=file:///"+filename+"]"

def getColor(score):
    if score == "从未参赛":
        return "#FFF0F5"
    elif score == "灰名":
        return "gray"
    elif score == "绿名":
        return "green"
    elif score == "青名":
        return "#03a89e"
    elif score == "蓝名":
        return "blue"
    elif score == "紫名":
        return "#a0a"
    elif score == "橙名":
        return "#ff8c00"
    elif score == "黄名":
        return "#ff8c00"
    elif score == "红名":
        return "#ff0000"
    elif score == "大红名":
        return "#ff0000"
    elif score == "红黑":
        return "#000000"
# 刷题排行榜
def getUserAcRank(user_name):
    users = []
    monday_stamp = getMonday()
    for handle in user_name.keys():
        params = {
            "handle": handle,
            "from": "1",
            "count": "100",
        }
        response = RES.get(url=url_cf + "/user.status", params=params, headers=headers)
        # 不断尝试直到请求成功
        while response.status_code != 200:
            sleep(1.2)
            response = RES.get(url=url_cf + "/user.status", params=params, headers=headers)
        res = response.json().get("result")
        ac_number = 0  # 总数过题数
        total = 0  # 总提交数
        cnt = 0
        for j in res:
            timestamp = j.get("creationTimeSeconds")  # 获取提交时间戳
            if timestamp < monday_stamp:  # 如果是上周的提交，则忽略
                cnt += 1
                break
            if j.get("verdict") != "OK":  # 只统计正确代码
                total += 1
                continue
            total += 1
            ac_number += 1
        users.append(UserSubmission(user_name[handle.lower()], handle, ac_number, total))
    users.sort(reverse=False)
    imgx = []
    imgy = []
    for i in range(0, len(users)):
        imgx.append(users[i].name)
        imgy.append(users[i].ac_number)
    matplotlib.rcParams['font.sans-serif'] = ["SimHei"]
    matplotlib.rcParams["axes.unicode_minus"] = False
    plt.figure(figsize=(10, 15))
    plt.barh(imgx, imgy, height=0.5)
    plt.title("本周ac数量排行榜")
    plt.xlabel("数量")
    plt.ylabel("姓名")
    for i, v in enumerate(imgy):
        plt.text(v + 1, i, str(v), fontweight='bold')
    filename = "E:\go_chttp\data\images\\cf_ac_rank.png"
    plt.savefig(filename)
    return "[CQ:image,file=file:///" + filename + "]"

# 获取即将开始的比赛信息
def getContests():
    response = RES.get(url=url_cf + "/contest.list")
    while response.status_code != 200:
        response = RES.get(url=url_cf + "/contest.list")
        sleep(0.3)
    res = response.json().get("result")
    contests = []
    for i in res:
        if i.get("phase") == "FINISHED":
            break
        contest = {
            "name": i.get("name"),
            "begin_time": formatDate(i.get("startTimeSeconds")),
            "end_time": formatDate(i.get("startTimeSeconds") + i.get("durationSeconds")),
            "type": i.get("type"),
            "status": i.get("phase"),
            "relative_time": i.get("relativeTimeSeconds"),
            "id":i.get("id"),
        }
        reset = abs(i.get("relativeTimeSeconds"))
        if reset > 7*24*60*60 :
            continue
        contests.append(contest)
    message = "《Codeforces 比赛日历》\n "
    if len(contests) == 0:
        message += "[空空如也]\t\t\n\n"
        return message
    for i in contests[::-1]:
        message += " 	比赛名称 : " + i["name"] + "     \n" \
                    + " 	比赛链接： https://codeforces.com/contestRegistration/" + str(i["id"]) + "     \t\n" \
                   + " 	开始时间 : " + i["begin_time"] + "     \t\n" \
                   + " 	结束时间 : " + i["end_time"] + "     \t\n" \
                   + " 	比赛类型 : " + i["type"] + "     \t\n"
        if i["status"] != "BEFORE":
            message += " 	比赛状态 : 进行中...\t\n\n"
        else:
            message += " 	比赛状态 : 未开始，距开始剩余 " + formatSeconds(abs(i["relative_time"])) + "\t\n\n"
    now_time = datetime.now()
    now_time = datetime.strftime(now_time, '%Y-%m-%d %H:%M:%S')
    message = message + "更新时间 : " + now_time
    return message

def getUser(nickname):
    params = {
        "handles": nickname
    }
    response = RES.get(url=url_cf + "/user.info", params=params)
    while response.status_code != 200:
        response = RES.get(url=url_cf + "/user.info", params=params)
        sleep(0.3)
    res = response.json().get("result")
    message = ""
    if len(res) == 0 :
        message = "查询失败 "+nickname+"可能不存在"
        return message
    else :
        score = 0
        if res[0].get("rating") is not None:
            score = res[0].get("rating")
        maxScore = 0
        if res[0].get("maxRating") is not None:
            maxScore = res[0].get("maxRating")
        lastOnlineTimeSeconds = datetime.fromtimestamp(res[0].get("lastOnlineTimeSeconds")).strftime("%Y-%m-%d %H:%M:%S")  # 格式化为字符串
        message = message + "handle: " +res[0].get("handle") +"\n" + \
                  "rating: " + str(score) + "(" +  rating_color[res[0].get("rank")] + ")" +"\n" + \
                    "max_Raing: " + str(maxScore) + "(" + rating_color[res[0].get("rank")] + ")"  +"\n" + \
                    "last_onlie_time: " + lastOnlineTimeSeconds +"\n"
        return message
# 发送 rating 排名至 QQ 群
def sendGroupRatingRank(group_id, user_name, u_id=None, flag=True):
    message = getUserRatingRank(user_name)
    data = {
        "group_id": group_id,
        "message": message
    }
    sleep(Rating_Rank_time)  # 等待获取数据
    requests.post(url=url_reboot + "/send_group_msg", json=data)


# 发送 rating 排名（私聊）
def sendPrivateRatingRank(uid, user_name):
    data = {
        "user_id": uid,
        "message": getUserRatingRank(user_name)
    }
    sleep(Rating_Rank_time)  # 等待获取数据
    requests.post(url=url_reboot + "/send_private_msg", json=data)


def sendGroup(group_id, message):
    data = {
        "group_id": group_id,
        "message": message
    }
    requests.post(url=url_reboot + "/send_group_msg", json=data)


# 发送ac排名至 QQ 群
def sendGroupAcRank(group_id, user_name, u_id=None, flag=True):
    messages = getUserAcRank(user_name)
    data = {
        "group_id": group_id,
        "message": messages
    }
    sleep(AC_Rank_Time)  # 等待获取数据
    requests.post(url=url_reboot + "/send_group_msg", json=data)


# 发送ac排名（私聊）
def sendPrivateAcRank(uid, user_name):
    messages = getUserAcRank(user_name)
    data = {
        "user_id": uid,
        "message": messages
    }
    sleep(AC_Rank_Time)  # 等待获取数据
    requests.post(url=url_reboot + "/send_private_msg", json=data)


# 发送比赛日历至 QQ 群
def sendGroupContests(group_id, nickname,u_id=None, flag=True):
    if not flag:
        pass
    data = {
        "group_id": group_id,
        "message":  getContests()
    }
    requests.post(url=url_reboot + "/send_group_msg", json=data)


# 发送比赛日历（私聊）
def sendPrivateContests(uid):
    message = getContests()
    data = {
        "user_id": uid,
        "message": message
    }
    requests.post(url=url_reboot + "/send_private_msg", json=data)


# 艾特成员
# def sendAT(group_id, u_id, nickname,flag=True):
#     if not flag:
#         pass
#     if u_id is None:
#         message = "[CQ:at,qq=all]"
#     else:
#         message = "[CQ:at,qq=" + str(u_id) + ",name="+nickname+"]"
#     data = {
#         "group_id": group_id,
#         "message": message,
#     }
#     requests.post(url=url_reboot + "/send_group_msg", json=data)

def sendPrivateHelp(uid):
    message = "获取未来一周比赛列表：cf -c 或者 cf contests \n" + \
            "获取ACM rank榜: cf -r 或者 cf rank \n" + \
            "获取本周AC题目榜: cf -a 或者 cf acRank\n" + \
            "获取某用户的详细信息：cf -u username 或者 cf user username，其中username为cf用户名\n" + \
            "获取帮助：cf -h或者cf help\n"
    data = {
        "user_id":uid,
        "message":message
    }
    requests.post(url=url_reboot + "/send_private_msg", json=data)

def sendGroupHelp(group_id,uid):
    message = "获取未来一周比赛列表：cf -c 或者 cf contests \n" + \
              "获取ACM rank榜: cf -r 或者 cf rank \n" + \
              "获取本周AC题目榜: cf -a 或者 cf acRank\n" + \
              "获取某用户的详细信息：cf -u username 或者 cf user username，其中username为cf用户名\n" + \
              "获取帮助：cf -h或者cf help\n"
    data = {
        "group_id": group_id,
        "message": message
    }
    requests.post(url=url_reboot + "/send_group_msg", json=data)

def sendPrivateUser(uid,nickname):
    message = getUser(nickname)
    data = {
        "user_id":uid,
        "message":message
    }
    requests.post(url=url_reboot + "/send_private_msg", json=data)

def sendGroupUser(group_id,uid,nickname):
    message = getUser(nickname)
    data = {
        "group_id": group_id,
        "message": message
    }
    requests.post(url=url_reboot + "/send_group_msg", json=data)

def sendPrivateAtcoderContests(uid,nickname):
    contests = get_atcoder_contests()
    message = "《Atcoder比赛日历》\n"
    for x in contests:
        contest_time = list(map(str, x['contest_time']))
        message = message + " 	比赛名字：\t" + x['name'] + "\n" + " 	比赛链接：\t" + x['link'] + "\n" + " 	比赛时间：\t" + \
                  contest_time[0] + "至" + contest_time[1] + "\n\n"
    now_time = datetime.now()
    now_time = datetime.strftime(now_time, '%Y-%m-%d %H:%M:%S')
    message = message + "更新时间 : " + now_time
    data = {
        "user_id":uid,
        "message":message
    }
    requests.post(url=url_reboot + "/send_private_msg", json=data)

def sendGroupAtcoderContests(group_id,uid,nickname):
    contests = get_atcoder_contests()
    message = "《Atcoder比赛日历》\n"
    for x in contests:
        contest_time = list(map(str, x['contest_time']))
        message = message + " 	比赛名字：\t" + x['name'] + "\n" + " 	比赛链接：\t" + x['link'] + "\n" + " 	比赛时间：\t" + contest_time[0] + "至" + contest_time[1] + "\n\n"
    now_time = datetime.now()
    now_time = datetime.strftime(now_time, '%Y-%m-%d %H:%M:%S')
    message = message + "更新时间 : " + now_time
    data = {
        "group_id": group_id,
        "message": message
    }
    requests.post(url=url_reboot + "/send_group_msg", json=data)

def sendPrivateNowCoderContests(uid,nickname):
    contests = get_nowcoder_contests()
    message = "《牛客比赛日历》\n"
    for x in contests:
        contest_time = list(map(str, x['contest_time']))
        message = message + " 	比赛名字：\t" + x['name'] + "\n" + " 	比赛链接：\t" + x['link'] + "\n" + " 	比赛时间：\t" + \
                  contest_time[0] + "至" + contest_time[1] + "\n\n"
    now_time = datetime.now()
    now_time = datetime.strftime(now_time, '%Y-%m-%d %H:%M:%S')
    message = message + "更新时间 : " + now_time
    data = {
        "user_id":uid,
        "message":message
    }
    requests.post(url=url_reboot + "/send_private_msg", json=data)

def sendGroupNowCoderContests(group_id,uid,nickname):
    contests = get_nowcoder_contests()
    print(contests)
    message = "《牛客比赛日历》\n"
    for x in contests:
        contest_time = list(map(str, x['contest_time']))
        message = message + " 	比赛名字：\t" + x['name'] + "\n" + " 	比赛链接：\t" + x['link'] + "\n" + " 	比赛时间：\t" + \
                  contest_time[0] + "至" + contest_time[1] + "\n\n"
    now_time = datetime.now()
    now_time = datetime.strftime(now_time, '%Y-%m-%d %H:%M:%S')
    message = message + "更新时间 : " + now_time
    data = {
        "group_id": group_id,
        "message": message
    }
    requests.post(url=url_reboot + "/send_group_msg", json=data)
